package com.ld.security.common.tomcat.util;

import cn.hutool.http.HttpUtil;
import com.ld.security.common.core.util.JsonUtil;
import com.ld.security.common.core.util.ReflectionUtil;
import lombok.SneakyThrows;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;


public class SessionUtil {


    protected static String appName ;


    public static void setAppName(String appName) {
        SessionUtil.appName = appName;
    }



    public static HttpSession getSession() {
        HttpServletRequest request = getRequest();
        HttpSession session = request.getSession();
        return session;
    }
    public static String getSessionId() {
        return getSession().getId();
    }

    public static HttpServletRequest getRequest () {
        Object v =  RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();

        HttpServletRequest request = servletRequestAttributes.getRequest();
        return request;
    }

    public static HttpServletResponse getResponse() {
        HttpServletResponse response = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse();

        return response;
    }

    @SneakyThrows
    public static String getBody() {
        HttpServletRequest request =  getRequest ();
        BufferedReader br = null;
        br = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8"));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        return sb.toString();

    }


    /**
     * 获得请求url
     * @return
     */
    public static String getUrl(){
        return getRequest().getRequestURI();
    }

    /**
     * 获得请求url
     * @return
     */
    public static String getAppUrl(){
        return "/"+appName+ getRequest().getRequestURI();
    }


    public static void set(String key,Object val) {
        HttpSession session = getSession();
        session.setAttribute(key, val);
    }

    public static <E> E get(String key) {
        HttpSession session = getSession();
        E val = (E)session.getAttribute(key);
        return val;
    }

    public static String getCookie(String cookieName){
        HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();

        Cookie[] cookies =  request.getCookies();
        if(cookies != null){
            for(Cookie cookie : cookies){
                if(cookie.getName().equals(cookieName)){
                    return cookie.getValue();
                }
            }
        }

        return null;
    }

    /**
     * 获得请求头参数
     *
     * @param name
     * @return
     */
    public static String getHeader(String name) {
        HttpServletRequest request = getRequest();
        return request.getHeader(name);
    }
    public static String getParameter(String name) {
        HttpServletRequest request = getRequest();
        return request.getParameter(name);
    }


    /**
     * 获得请求头参数
     *
     * @param name
     * @return
     */
    public static Map<String,String> getHeaderMap() {
        Map map =  new HashMap<>();
        HttpServletRequest request = getRequest();
        Enumeration<String> es =  request.getHeaderNames();
        if(es.hasMoreElements()){
            String key = es.nextElement();
            String val =  request.getHeader(key);
            map.put(key,val);
        }
        return map;
    }


    /**
     * 获取ip地址
     *
     * @return
     */
    public static String getIPAddress() {
        HttpServletRequest request = getRequest();
        String ip = null;

        //X-Forwarded-For：Squid 服务代理
        String ipAddresses = request.getHeader("X-Forwarded-For");

        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //Proxy-Client-IP：apache 服务代理
            ipAddresses = request.getHeader("Proxy-Client-IP");
        }

        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //WL-Proxy-Client-IP：weblogic 服务代理
            ipAddresses = request.getHeader("WL-Proxy-Client-IP");
        }

        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //HTTP_CLIENT_IP：有些代理服务器
            ipAddresses = request.getHeader("HTTP_CLIENT_IP");
        }

        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //X-Real-IP：nginx服务代理
            ipAddresses = request.getHeader("X-Real-IP");
        }

        //有些网络通过多层代理，那么获取到的ip就会有多个，一般都是通过逗号（,）分割开来，并且第一个ip为客户端的真实IP
        if (ipAddresses != null && ipAddresses.length() != 0) {
            ip = ipAddresses.split(",")[0];
        }

        //还是不能获取到，最后再通过request.getRemoteAddr();获取
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            ip = request.getRemoteAddr();
        }

        return ip;
    }

  public static String getCity() {
        return getCity("");
  }

        public static String getCity(String ip){
        HashMap args =  new HashMap<>();
        args.put("ip",ip);
        args.put("ak","lGkzn9AqD4efCNNic9BxFG5LcwXYll5I");
        args.put("coor","bd09ll");
        String html =
                HttpUtil.get("http://api.map.baidu.com/location/ip",args);

        Map<String,Object> val =   JsonUtil.toObject(html,Map.class);


        Map map =         ReflectionUtil.invokeGetter(val,"content.address_detail");

        String  province = (String)map.get("province");
        String  city =(String)  map.get("city");
        return province+city;
    }
}